package velox.jcr.mapper;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.transaction.support.TransactionSynchronization;
import org.springframework.transaction.support.TransactionSynchronizationManager;


public class UnitOfWorkHolder {
	private static final Logger logger = LoggerFactory.getLogger(UnitOfWorkHolder.class);
	private static SecondLevelCache secondLevelCache;
	private static MapperManager mapperManager;
	private static Filter filter;
	
	public static UnitOfWork get() {
		UnitOfWork uow = (UnitOfWork) TransactionSynchronizationManager.getResource("uow");
		if (uow == null) {
			logger.debug("Creating new UnitOfWork");
			
			uow = new DefaultUnitOfWork(mapperManager, secondLevelCache, filter);
			TransactionSynchronizationManager.bindResource("uow", uow);

			logger.debug("Registering SLC transaction completion listener");
			TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() {
				public void afterCompletion(int arg0) {
					if (! TransactionSynchronizationManager.isCurrentTransactionReadOnly()) {
						((DefaultUnitOfWork) TransactionSynchronizationManager.getResource("uow")).invalidateSecondLevelCache();
					}
					TransactionSynchronizationManager.unbindResource("uow");
				}

				public void afterCommit() { }
				public void beforeCommit(boolean arg0) { }
				public void beforeCompletion() { }
				public void resume() { }
				public void suspend() {	}
			});
		}
		return uow;
	}
	
	public static void initialize(SecondLevelCache secondLevelCache, MapperManager mapperManager, Filter filter) {
		UnitOfWorkHolder.secondLevelCache = secondLevelCache;
		UnitOfWorkHolder.mapperManager = mapperManager;
		UnitOfWorkHolder.filter = filter;
	}
	
	public static void setFilter(Filter filter) {
		UnitOfWorkHolder.filter = filter;
	}
}
